package com.lingtianyu.tech.erbaoshen.core.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.lingtianyu.tech.erbaoshen.core.exception.SerializeExecuteNotFoundException;
import com.lingtianyu.tech.erbaoshen.core.util.serialize.SerializeExecute;
import io.vavr.Tuple;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class SerializeUtil {
    private final Map<String, SerializeExecute> serializeExecuteMap;
    private final List<SerializeExecute> serializeExecutes;

    public SerializeUtil(List<SerializeExecute> serializeExecutes) {
        this.serializeExecutes = serializeExecutes;
        serializeExecuteMap = io.vavr.collection.List.ofAll(serializeExecutes).toJavaMap(s -> Tuple.of(s.getType(), s));
    }

    public Object unSerializeParams(Object param, Type type, String serializeType) {
        SerializeExecute serializeExecute1 = getSerializeExecute(serializeType);
        if (param == null) {
            return null;
        }
        if (type instanceof Class) {
            Class<?> aClass = (Class<?>) type;
            if (aClass.isArray()) {
                serializeExecute1.unSerializeArray(param, type);
            } else if (String.class.equals(aClass)) {
                return serializeExecute1.unSerializeString(param);
            } else if (Date.class.equals(aClass)) {
                return serializeExecute1.unSerializeDate(param);
            } else if (boolean.class.equals(aClass) || Boolean.class.equals(aClass)) {
                return serializeExecute1.unSerializeBoolean(param);
            } else if (char.class.equals(aClass) || Character.class.equals(aClass)) {
                return serializeExecute1.unSerializeChar(param);
            } else if (byte.class.equals(aClass) || Byte.class.equals(aClass)) {
                return serializeExecute1.unSerializeByte(param);
            } else if (short.class.equals(aClass) || Short.class.equals(aClass)) {
                return serializeExecute1.unSerializeShort(param);
            } else if (int.class.equals(aClass) || Integer.class.equals(aClass)) {
                return serializeExecute1.unSerializeInt(param);
            } else if (long.class.equals(aClass) || Long.class.equals(aClass)) {
                return serializeExecute1.unSerializeLong(param);
            } else if (float.class.equals(aClass) || Float.class.equals(aClass)) {
                return serializeExecute1.unSerializeFloat(param);
            } else if (double.class.equals(aClass) || Double.class.equals(aClass)) {
                return serializeExecute1.unSerializeDouble(param);
            } else if (BigDecimal.class.equals(aClass)) {
                return serializeExecute1.unSerializeBigDecimal(param);
            } else {
                return serializeExecute1.unSerializeObject(param, type);
            }
        } else {
            return serializeExecute1.unSerializeDefault(param, type);
        }
        return serializeExecute1.unSerializeDefault(param, type);
    }


    //最终都是json格式，除非是使用序列化成base64的string，则会是json中套用字符串
    public String toSerializeParams(Object param, String serializeType) {
        if (param == null) {
            return null;
        }
        SerializeExecute serializeExecute = getSerializeExecute(serializeType);
        return serializeExecute.serializeParam(param);
    }

    private SerializeExecute getSerializeExecute(String serializeType1) {
        String serializeType = getDefaultSerializeType(serializeType1);
//        SerializeExecute serializeExecute1 = serializeExecuteMap.computeIfAbsent(serializeType, (t) -> {
//            for (SerializeExecute serializeExecute : serializeExecutes) {
//                if (serializeExecute.getType().equals(serializeType)) {
//                    return serializeExecute;
//                }
//            }
//            throw new SerializeExecuteNotFoundException(serializeType + " not found in erBaoShen SerializeExecutes");
//        });
        return serializeExecuteMap.get(serializeType);
    }

    private String getDefaultSerializeType(String serializeType) {
        if (serializeType == null || serializeType.isEmpty()) {
            return "jackson";
        }
        return serializeType;
    }
}
